package com.xuanyang.dormrepair.config.hook;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xuanyang.dormrepair.model.entity.FloorRoom;
import com.xuanyang.dormrepair.model.entity.User;
import com.xuanyang.dormrepair.service.FloorRoomService;
import com.xuanyang.dormrepair.service.UserService;
import com.xuanyang.dormrepair.utils.Const;
import com.xuanyang.dormrepair.utils.JwtKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.annotation.Annotation;

/**
 * @AUTHOR soft
 * @DATE 2019/5/22 20:41
 * @DESCRIBE 用户登录拦截器 通用的
 */
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private FloorRoomService roomService;

    @Autowired
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {

        if (handler instanceof  HandlerMethod) {
            OpenApi openApi = getAnn((HandlerMethod) handler, OpenApi.class);
            AppLogin appLogin = getAnn((HandlerMethod) handler, AppLogin.class);
            AdminLogin adminLogin = getAnn((HandlerMethod) handler, AdminLogin.class);
            OnceLogin onceLogin = getAnn((HandlerMethod) handler, OnceLogin.class);
            if (openApi != null ||
                    (appLogin == null && adminLogin == null && onceLogin == null)) return true;


            // 手机端的登录验证
            if (appLogin != null && authApp(request, response)) {
                return true;
            }

            // 管理员的登 录验证
            if (adminLogin != null && authAdmin(request, response)) {
                return true;
            }

            // 有一方登录即可
            if (onceLogin != null && (authApp(request, response) || authAdmin(request, response))) {
                return true;
            }
        }

        if (request.getMethod().equalsIgnoreCase("get")) {
            response.sendRedirect("/login");
        } else {
            response.sendRedirect("/api/nologin");
        }
        return false;
    }

    private boolean authAdmin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = (User) request.getSession().getAttribute(Const.USER);

        if (user != null) {
            User su = userService.byUsername(user.getUsername());
            return su != null && su.getPassword().equals(user.getPassword());
        }
        return false;
    }

    private boolean authApp(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            token = request.getParameter("token");
        }

        String[] nos = JwtKit.getNos(token);
        FloorRoom room = roomService.byNos(nos);

        if (room != null) {
            if (JwtKit.verify(token, room.getUsername(), room.getPassword())) {
                request.setAttribute(Const.USER, room);
                return true;
            }
        }
        return false;
    }

    /**
     * 从方法上获取注解
     */
    private <A extends Annotation> A getAnn(HandlerMethod method, Class<A> clz) {
        A annotation = method.getMethodAnnotation(clz);
        if (annotation == null) {
            annotation = method.getBeanType().getAnnotation(clz);
        }
        return annotation;
    }
}
